package progetto.visualizzazione;

import grafi.Arco;
import grafi.Grafo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;

import progetto.misure.Misuratore;
import progetto.socialnetwork.GrafoTwitter;

import socialnetworks.GrafoYouTube;
import socialnetworks.YouTubeDataExtractor;

import com.google.gdata.util.ServiceException;

public class Visualizzatore {
	
	
	public GrafoTwitter grafoTwitter;
	public ArrayList <Double> pageRank;
    public ArrayList <Double> hits;
    public ArrayList <Double> between;
    public ArrayList <Double> boundedBetween; 
	
	public Misuratore misuratore;
	static final String delimitatore = "!:!"; //separatore di sezione
	
public Visualizzatore(){
	grafoTwitter=GrafoTwitter.loadData();
	misuratore = new Misuratore (grafoTwitter);
	pageRank= getPageRank();
	hits= getHits();
	between=getBetween();
	boundedBetween=getBoundedBetween(2);
}
	
	public ArrayList <Double> getPageRank (){
		
		double [] pr = misuratore.getPageRank();
		ArrayList <Double> pageR =new ArrayList <Double> ();
		for(int i=0;i<pr.length;i++)
			pageR.add(pr[i]);
		return pageR;
	}
	
	public ArrayList <Double> getHits(){
		double [] pr = misuratore.getHits();
		ArrayList <Double> h =new ArrayList <Double> ();
		for(int i=0;i<grafoTwitter.getN();i++)
			h.add(pr[i]);
		return h;
	}
	public  ArrayList <Double> getBetween(){
		double [] pr = misuratore.getBetween();
		ArrayList <Double> h =new ArrayList <Double> ();
		for(int i=0;i<grafoTwitter.getN();i++)
			h.add(pr[i]);
		return h;
	}
	public ArrayList <Double> getBoundedBetween(int k){
		double [] pr = misuratore.getBoundedBetween(k);
		ArrayList <Double> h =new ArrayList <Double> ();
		for(int i=0;i<grafoTwitter.getN();i++)
			h.add(pr[i]);
		return h;
	}
	
	/*public static GrafoTwitter getGrafoTwitter()  throws ServiceException, IOException{
		//YouTubeDataExtractor extr=new YouTubeDataExtractor();
		//List<String> seedIds=extr.query("android");		
		//List<String> seedIds=new ArrayList<String>();
		//seedIds.add("iSph2I-LLKs");
		GrafoTwitter g=new GrafoTwitter(numeroNodi);
		/*Iterator<Arco> it=g.archi();
		while(it.hasNext())
			System.out.println(it.next());
		String titolo="";
		for(int i=0;i<numeroNodi;i++)
		{	String id=g.id(i);
			if(id.startsWith("VID::")){
				titolo=extr.titolo(id.substring(5));
				System.out.println(titolo);
			}
		}
		
		return g;
	}
*/
	public boolean scriviTxtFile (){
		
		try {
		      FileOutputStream file = new FileOutputStream("twittertest.txt");
		      PrintStream Output = new PrintStream(file);
		      Output.println();
		      Output.println(delimitatore);
		      
		      scriviArchi(Output);		      
		      Output.println(delimitatore);

		      scriviNodi(Output);
		      Output.println(delimitatore);

		      scriviPageRank(Output);
		      
			  Output.close();
		      System.out.println("scrittura su TESTO terminata con successo");
		      return true;
		} catch (IOException e) {
		      System.out.println("Errore: " + e);
		      System.exit(1);
		    }
		return false;
	}
	
	///questo serve per il grafo reverse!!!
public static boolean scriviDotFile (GrafoYouTube g){
		
		try {
		      FileOutputStream file = new FileOutputStream("secondo.dot");
		      PrintStream Output = new PrintStream(file);
		      Output.println("digraph G {");
		      
		    //salva nodi
		      for(int i=0;i<g.getN();i++){	
					String id=g.id(i).substring(5);
					Output.println("\""+id+"\";");
			  }
		      
		      //salva archi
		      Iterator<Arco> it=g.archi();
		      while(it.hasNext()){
			    	  Arco a=it.next();
			    	  Output.println("\""+g.id(a.getIn()).substring(5)+"\" -> \""+g.id(a.getFin()).substring(5)+"\";");
			    	  //Output.println(a.getIn()+","+a.getFin());
					//output.flush();
					}
		      
		      Output.println("}");
			  Output.close();
		      System.out.println("scrittura terminata con successo");
		      return true;
		} catch (IOException e) {
		      System.out.println("Errore: " + e);
		      System.exit(1);
		    }
		return false;
	}	
public boolean exportDotFile(){
		
		try {
		      FileOutputStream file = new FileOutputStream("Nodi200.dot");
		      PrintStream Output = new PrintStream(file);
		      Output.println("digraph G {");
		      
		    //salva nodi
		      for(int i=0;i<grafoTwitter.getN();i++){	
					String id=grafoTwitter.getId(i);
					Output.println("\""+id+"\";");
			  }
		      
		      //salva archi
		      Iterator<Arco> it=grafoTwitter.archi();
		      while(it.hasNext()){
			    	  Arco a=it.next();
			    	  Output.println("\""+grafoTwitter.getId(a.getIn())+"\" -> \""+grafoTwitter.getId(a.getFin())+"\";");
			    	  //Output.println(a.getIn()+","+a.getFin());
					//output.flush();
					}
		      
		      Output.println("}");
			  Output.close();
		      System.out.println("scrittura terminata con successo");
		      return true;
		} catch (IOException e) {
		      System.out.println("Errore: " + e);
		      System.exit(1);
		    }
		return false;
	}
	
public boolean exportXmlFile (){
	
	
	
	try {
	      FileOutputStream file = new FileOutputStream("Grafo200.graphml");
	      PrintStream Output = new PrintStream(file);
	      Output.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?><graphml xmlns=\"http://graphml.graphdrawing.org/xmlns/graphml\" xmlns:visone=\"http://visone.info/xmlns\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:y=\"http://www.yworks.com/xml/graphml\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns/graphml http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd\">");
	      Output.println("<key attr.name=\"visone.nodeID\" attr.type=\"int\" for=\"node\" id=\"d0\"/>");
	      Output.println("<key attr.name=\"id\" attr.type=\"string\" for=\"node\" id=\"d6\"/>");
	      Output.println("<key for=\"node\" id=\"d14\" yfiles.type=\"nodegraphics\"/>");
	      Output.println("<key attr.name=\"visone.confirmation\" attr.type=\"int\" for=\"edge\" id=\"d15\"/>");
	      Output.println("<key attr.name=\"visone.direction\" attr.type=\"boolean\" for=\"edge\" id=\"d16\"/>");
	      Output.println("<key attr.name=\"id\" attr.type=\"string\" for=\"edge\" id=\"d17\"/>");
	      Output.println("<key for=\"edge\" id=\"d19\" yfiles.type=\"edgegraphics\"/>");
	      Output.println("<key for=\"graph\" id=\"d20\" visone.type=\"properties\"/>");
	      Output.println("<key for=\"graphml\" id=\"d23\" yfiles.type=\"resources\"/>");
	      Output.println("<key id=\"pagerank\" for=\"node\" attr.name=\"pagerank\" attr.type=\"double\"/>");
	      Output.println("<key id=\"hits-auth\" for=\"node\" attr.name=\"hits-auth\" attr.type=\"double\"/>");
	      Output.println("<key id=\"betw-cent\" for=\"node\" attr.name=\"betw-cent\" attr.type=\"double\"/>");
	      Output.println("<key id=\"boun-betw-cent\" for=\"node\" attr.name=\"boun-betw-cent\" attr.type=\"double\"/>");
	      Output.println("<graph id=\"G\" edgedefault=\"directed\">");
	      
	    //salva nodi
	      for(int i=0;i<grafoTwitter.getN();i++){	
				//String id=grafoTwitter.getId(i);
				Output.println("<node id=\""+i+"\">");
				Output.println("<data key=\"pagerank\">"+pageRank.get(i)+"</data>");
				Output.println("<data key=\"hits-auth\">"+hits.get(i)+"</data>");
				Output.println("<data key=\"betw-cent\">"+between.get(i)+"</data>");
				Output.println("<data key=\"boun-betw-cent\">"+boundedBetween.get(i)+"</data>");
				Output.println("<data key=\"d0\">"+i+"</data>");
				Output.println("<data key=\"d6\">"+i+"</data>");
				Output.println("<data key=\"d14\">");
				Output.println("<visone:shapeNode>");
				Output.println("<y:ShapeNode>");
				Output.println("<y:Geometry height=\"30.0\" width=\"30.0\" x=\"184.9148807905459\" y=\"276.74724895295066\"/>");
				Output.println("<y:Fill color=\"#3399FF\" transparent=\"false\"/>");
				Output.println("<y:BorderStyle color=\"#000000\" type=\"line\" width=\"1.0\"/>");
				Output.println("<y:Shape type=\"roundrectangle\"/>");
				Output.println("</y:ShapeNode>");
				Output.println("</visone:shapeNode>");
				Output.println("</data>");
				Output.println("</node>");
		  }
	      
	      //salva archi
	      Iterator<Arco> it=grafoTwitter.archi();
	      int i=0;
	      while(it.hasNext()){
		    	  Arco a=it.next();
		    	  Output.println("<edge id=\"e"+i+"\" source=\""+a.getIn()+"\" target=\""+a.getFin()+"\">");
		    	  Output.println("<data key=\"d15\">3</data>");
		    	  Output.println("<data key=\"d16\">true</data>");
		    	  Output.println("<data key=\"d17\">e"+i+"</data>");
		    	  Output.println("<data key=\"d19\">");
		    	  Output.println("<visone:polyLineEdge>");
		    	  Output.println("<y:PolyLineEdge>");
		    	  Output.println("<y:Path sx=\"0.0\" sy=\"0.0\" tx=\"0.0\" ty=\"0.0\"/>");
		    	  Output.println("<y:LineStyle color=\"#000000\" type=\"line\" width=\"2.0\"/>");
		    	  Output.println("<y:Arrows source=\"none\" target=\"true\"/>");
		    	  Output.println("<y:BendStyle smoothed=\"false\"/>");
		    	  Output.println("</y:PolyLineEdge>");
		    	  Output.println("<visone:edgeRealizerData>");
		    	  Output.println("<visone:line style=\"continuous\" width=\"2.0\"/>");
		    	  Output.println("</visone:edgeRealizerData>");
		    	  Output.println("</visone:polyLineEdge>");
		    	  Output.println("</data>");
		    	  Output.println("</edge>");
		    	  i++;
				}
	      
	      Output.println("</graph>");
	      Output.println("</graphml>");
		  Output.close();
	      System.out.println("scrittura terminata con successo");
	      return true;
	} catch (IOException e) {
	      System.out.println("Errore: " + e);
	      System.exit(1);
	    }
	return false;
}

	public  void scriviArchi(PrintStream output){
		Iterator<Arco> it=grafoTwitter.archi();
		while(it.hasNext()){
	    	  Arco a=it.next();
	    	  output.println("--"+a.getIn()+","+a.getFin());
			//output.flush();
			}
	}
	
	public  void scriviPageRank(PrintStream output){
		output.println("PageRank");
		for(int i=0;i<grafoTwitter.getN();i++)
			output.println(pageRank.get(i));
	}
	
	public  void scriviNodi(PrintStream output){
		//String titolo="";
		//YouTubeDataExtractor extr=new YouTubeDataExtractor();
		for(int i=0;i<grafoTwitter.getN();i++){	
			String id=grafoTwitter.getId(i);
			output.println(id);
		}
	}
	public static  ArrayList<String> readFromFile(String nomeFile) throws IOException {
		 ArrayList<String> result=new ArrayList<String>();

		   if (nomeFile != null) {
		       File f = new File(nomeFile);
		       BufferedReader reader = null;
		       if (f.exists()) {
		           try {
		              reader = new BufferedReader(new FileReader(f));
		           
		              String tmp = null;
		              while((tmp = reader.readLine()) != null) {
		                  result.add(tmp);
		              }
		          
		           } finally {
		              if(reader != null)
		                  reader.close();
		           }
		       }
		   }
		   return result;
		}
	
// da modificareeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
	public static Grafo reverseGrafo() throws IOException, ServiceException {
		
		List <String>l=readFromFile("twittertest.txt");
		  int numeroNodi=Integer.parseInt (l.get(0));
		  List<String> seeds= new ArrayList<String>();
		  List<String> archi= new ArrayList<String>();
        for(String s: l){
        	if (s.startsWith("--")){
        		archi.add(new String(s.substring(2)));
        	}
        	if(s.startsWith("VID::")||s.startsWith("USR::"))
        		seeds.add(s);
        }
        
         Grafo g=new GrafoYouTube(numeroNodi,seeds,true);
        for(String st: archi){
        	for(int i=0;i<st.length();i++)
        	if(st.charAt(i)==','){
        	int n=Integer.parseInt(st.substring(0, i));
        	int m=Integer.parseInt(st.substring(i+1, st.length()));
        	g.aggiungiArco(new Arco(n,m));
        	}
        }
		return g;
	

	
}
}
